rank
Statistics Timm Mar10 Revised

Ranking a List of Numbers

Problem
=======

For various statistical tests, asets of numbers have to be converted
to their ranks.  For example, If sample "A" generated five values
(5,7,2,0,4) and sample "B" generates six values (4,8,2,3,6,7) then
these sort as follows:

  Samples A  A  B  B  A  B  A  B  A  B  B
  Values  0  2  2  3  4  4  5  6  7  7  8

This generates a set of ranks (and we use the average rank for when
the values are the same:

  Samples A  A   B   B  A   B   A  B  A   B   B
  Values  0  2   2   3  4   4   5  6  7   7   8
  ---------------------------------------------
  Ranks   1  2.5 2.5 4  5.5 5.5 7  8  9.5 9.5 11

Note that, when ranked in this manner, the largest value have the same
rank, regardless if they were was ten to a hundred times larger.  That
is, such rank tests are not susceptible to large outliers.

Solution
========

Synopsis
---------

  rank(arrayOfNumbers, ranks)

_Ranks_ is a set of key, value pairs wheich each key comes from _arrayOfNumbers_
and each value is the rank of the _key_.

Example
-------

 function Rank(  d,r) {
     split("1,1,1,1,1",   d,","); rank(d,r); o(r,"r1");
     split("1,2,3,4,5",   d,","); rank(d,r); o(r,"r5");
     split("1,1,10,10",   d,","); rank(d,r); o(r,"r110"); 
     split("1,1,10,10,20",d,","); rank(d,r); o(r,"r11020");
     split("5,7,2,1,4,4,8,2,3,6,7",d,","); 
	 rank(d,r); o(r,"ro");  
     print r[1] == 1
     print r[7] == 9.5
     print r[3] == 4
     print r[8] == 11
 }

Code
----

 function rank(data0,ranks,     \
               data,starter,n,old,start,skipping,sum,i,j,r) {
     starter="someCraZYsymBOL";
     n     = asort(data0,data)    
     old   = starter
     start = 1;
     delete ranks;
     for(i=1;i<=n;i++) {
	 skipping = (old == starter) || (data[i] == old);
	 if (skipping) {
	     sum += i 
	 } else {
	     r = sum/(i - start)
	     for(j=start;j<i;j++) 
		 ranks[data[j]] = r;
	     start = i;
	     sum   = i;
	 }
	 old=data[i]
     }
     if (skipping) {
	 ranks[data[n]] = sum/(i - start)
     } else {
	 if (! (data[n] in ranks))
	     ranks[data[n]] = n #int(r+1.4999)
     }
 }

Author
======

Tim Menzies

